﻿//////////////////////////////////////////////////////////////////////////
//   File Name: SwndStyle.h
//////////////////////////////////////////////////////////////////////////

#include "souistd.h"
#include "core/Swndstyle.h"
#include "core/Swnd.h"
#include "helper/SplitString.h"

namespace SOUI {

    SwndStyle::SwndStyle()
        : m_uAlign(Align_Center)
        , m_uVAlign(VAlign_Middle)
        , m_nTextAlign(0)
        , m_strCursor(_T("arrow"))
        , m_bDotted(1)
        , m_bTrackMouseEvent(0)
        , m_bBlendBackground(1)
        , m_nScale(100)
        , m_bMultiLines(FALSE) {
        m_crBg.color = CR_INVALID;
        m_crBorder.color = CR_INVALID;
        for(int i = 0; i < 4; i++) {
            m_crText[i].color = CR_INVALID;
        }
    }
    
    UINT SwndStyle::GetTextAlign() const {
        if(m_nTextAlign) {
            return m_nTextAlign;
        }
        
        UINT uRet = 0;
        switch(m_uAlign) {
            case Align_Center:
                uRet |= DT_CENTER;
                break;
            case Align_Right:
                uRet |= DT_RIGHT;
                break;
        }
        switch(m_uVAlign) {
            case VAlign_Middle:
                uRet |= DT_VCENTER;
                break;
            case VAlign_Bottom:
                uRet |= DT_BOTTOM;
                break;
        }
        if (!m_bMultiLines) {
            uRet |= DT_SINGLELINE;
        } else {
            uRet |= DT_WORDBREAK;
        }
        if(m_bDotted) {
            uRet |= DT_END_ELLIPSIS;
        }
        return uRet;
    }
    
    int SwndStyle::GetStates() {
        int fonts = 1, colors = 1;
        for(int i = 1; i < 4; i++) {
            if(m_ftText[i].GetFontPtr() != NULL) {
                fonts++;
            }
            if(m_crText[i].color != CR_INVALID) {
                colors++;
            }
        }
        return smax(fonts, colors);
    }
    
    COLORREF SwndStyle::GetTextColor( int iState ) {
        iState %= 4;
        if(m_crText[iState].color == CR_INVALID) {
            if (iState == 3) {
                return  SOUI::SApplication::getSingleton().GetDefTextGrayColor();
            } else if(m_crText[0].color == CR_INVALID) {
                return  SOUI::SApplication::getSingleton().GetDefTextColor();
            } else {
                return m_crText[0].color;
            }
        }
        return m_crText[iState].color;
    }
    
    IFontPtr SwndStyle::GetTextFont( int iState ) {
        iState %= 4;
        if(!m_ftText[iState].GetFontPtr()) {
            iState = 0;
        }
        return m_ftText[iState].GetFontPtr();
    }
    
    HRESULT SwndStyle::OnAttrMargin(const SStringW &strValue, BOOL bLoading) {
        _ParseLayoutSize4(strValue, m_rcMargin);
        return !bLoading ? S_OK : S_FALSE;
    }
    
    HRESULT SwndStyle::OnAttrMarginX(const SStringW &strValue, BOOL bLoading) {
        m_rcMargin[0] = m_rcMargin[2] = GETLAYOUTSIZE(strValue);
        return !bLoading ? S_OK : S_FALSE;
    }
    
    HRESULT SwndStyle::OnAttrMarginY(const SStringW &strValue, BOOL bLoading) {
        m_rcMargin[1] = m_rcMargin[3] = GETLAYOUTSIZE(strValue);
        
        return !bLoading ? S_OK : S_FALSE;
    }
    
    HRESULT SwndStyle::OnAttrExtend(const SStringW &strValue, BOOL bLoading) {
        SStringWList values;
        size_t nValues = SplitString(strValue, L',', values);
        if (nValues == 1) {
            m_rcExtend[0] = m_rcExtend[1] = GETLAYOUTSIZE(values[0]);
        } else {
            m_rcExtend[0] = GETLAYOUTSIZE(values[0]);
            m_rcExtend[1] = GETLAYOUTSIZE(values[1]);
        }
        
        return !bLoading ? S_OK : S_FALSE;
    }
    
    void SwndStyle::_ParseLayoutSize4(const SStringW &strValue, SLayoutSize layoutSizes[]) {
        SStringWList values;
        size_t nValues = SplitString(strValue, L',', values);
        if (nValues == 1) {
            layoutSizes[0] = layoutSizes[1] = layoutSizes[2] = layoutSizes[3] = GETLAYOUTSIZE(values[0]);
        } else if (nValues == 2) {
            layoutSizes[0] = layoutSizes[2] = GETLAYOUTSIZE(values[0]);
            layoutSizes[1] = layoutSizes[3] = GETLAYOUTSIZE(values[1]);
        } else if (nValues == 4) {
            layoutSizes[0] = GETLAYOUTSIZE(values[0]);
            layoutSizes[1] = GETLAYOUTSIZE(values[1]);
            layoutSizes[2] = GETLAYOUTSIZE(values[2]);
            layoutSizes[3] = GETLAYOUTSIZE(values[3]);
        }
    }
    
    HRESULT SwndStyle::OnAttrPadding(const SStringW &strValue, BOOL bLoading) {
        _ParseLayoutSize4(strValue, m_rcInset);
        return bLoading ? S_FALSE : S_OK;
    }
    
    
    void SwndStyle::SetScale(int nScale) {
        m_nScale = nScale;
        for(int i = 0; i < 4; i++) {
            m_ftText[i].UpdateFont(nScale);
        }
    }
    
    CRect SwndStyle::GetMargin() const {
        CRect rcRet;
        rcRet.left = m_rcMargin[0].toPixelSize(GetScale());
        rcRet.top = m_rcMargin[1].toPixelSize(GetScale());
        rcRet.right = m_rcMargin[2].toPixelSize(GetScale());
        rcRet.bottom = m_rcMargin[3].toPixelSize(GetScale());
        return rcRet;
    }
    
    CRect SwndStyle::GetPadding() const {
        CRect rcRet;
        rcRet.left = m_rcInset[0].toPixelSize(GetScale());
        rcRet.top = m_rcInset[1].toPixelSize(GetScale());
        rcRet.right = m_rcInset[2].toPixelSize(GetScale());
        rcRet.bottom = m_rcInset[3].toPixelSize(GetScale());
        return rcRet;
        
    }
    
    CSize SwndStyle::GetExtrend() const {
        CSize rcRet;
        rcRet.cx = m_rcExtend[0].toPixelSize(GetScale());
        rcRet.cy = m_rcExtend[1].toPixelSize(GetScale());
        return rcRet;
    }
    
    void SwndStyle::SetTextColor(int iState, COLORREF cr) {
        m_crText[iState].color = cr;
    }
    
    void SwndStyle::SetAlign(UINT uAlign) {
        m_uAlign = uAlign;
    }
    
    void SwndStyle::SetVAlign(UINT uAlign) {
        m_uVAlign = uAlign;
    }
    
    void SwndStyle::UpdateFont() {
        for(int i = 0; i < 4; i++) {
            m_ftText[i].UpdateFont(m_nScale);
        }
    }
    
    void SwndStyle::UpdateColor() {
        if (!m_crBg.name.IsEmpty()) {
            m_crBg.color = GETCOLOR(m_crBg.name);
        }
        
        if (!m_crBorder.name.IsEmpty()) {
            m_crBorder.color = GETCOLOR(m_crBorder.name);
        }
        
        for (int i = 0; i < 4; i++) {
            if (!m_crText[i].name.IsEmpty()) {
                m_crText[i].color = GETCOLOR(m_crText[i].name);
            }
        }
        
        
    }
    
    
}//namespace SOUI